package com.gree.sso.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gree.commom.utils.JsonUtil;
import com.gree.commom.utils.Md5Util;
import com.gree.commom.utils.UUIDUtil;
import com.gree.sso.entity.Admin;
import com.gree.sso.mapper.AdminMapper;
import com.gree.sso.service.SSOService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service(interfaceClass = SSOService.class)
@Component
public class SSOServiceImpl implements SSOService {

    private static Logger logger = LoggerFactory.getLogger(SSOServiceImpl.class);

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Value("${user.ticket}")
    private String userTicket;

    /**
     * 登录认证
     * @param admin
     * @return
     */
    @Override
    public String login(Admin admin) throws NoSuchAlgorithmException, JsonProcessingException {
        if (StringUtils.isEmpty(admin.getUsername().trim())) {
            logger.error("用户名为空");
            return null;
        }
        if (StringUtils.isEmpty(admin.getPassword().trim())) {
            logger.error("密码为空");
            return null;
        }
        //通过用户名和密码验证信息，如果用户信息唯一返回票据
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name",admin.getUsername()).eq("password",admin.getPassword());
        List<Admin> adminList = adminMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(adminList)||adminList.size()>1) {
            logger.error("用户名或密码不正确");
            return null;
        }
        Admin a = adminList.get(0);
        if (!a.getPassword().equals(Md5Util.getMd5WithSalt(admin.getPassword(),a.getEcSalt()))){
            logger.error("用户名或密码不正确");
            return null;
        }
        // 用户名和密码一致，登录成功返回票据信息,生成票据信息存入redis，页面借助cookie存储票据的key
        ValueOperations<String,String> valueOperations = redisTemplate.opsForValue();
        String ticket = UUIDUtil.getUUID();
        //设置30分钟失效
        valueOperations.set(userTicket + ":" + ticket, JsonUtil.object2JsonStr(a), 30, TimeUnit.SECONDS);
        //返回票据信息
        return ticket;
    }

    /**
     * 验证登录
     * @param ticket
     * @return
     */
    @Override
    public Admin validate(String ticket) throws UnsupportedEncodingException {
        if (StringUtils.isEmpty(ticket)) {
            logger.error("票据信息不存在");
            return null;
        }
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        String adminJson = valueOperations.get(userTicket + ":" + ticket);
        if (StringUtils.isEmpty(adminJson)){
            logger.error("票据对应的用户信息不存在");
            return null;
        }
        return JsonUtil.jsonStr2Object(adminJson,Admin.class);
    }

    /**
     * 用户退出
     * @param ticket
     */
    @Override
    public void logout(String ticket) {
        //清除用户信息
        redisTemplate.delete(userTicket+":"+ticket);
    }
}
